/* global React */
const CAR_TYRE_OPTIONS = [
  { value: '', label: 'All tyres' },
  { value: 'CS', label: 'CS' },
  { value: 'CM', label: 'CM' },
  { value: 'CH', label: 'CH' },
  { value: 'SH', label: 'SH' },
  { value: 'SM', label: 'SM' },
  { value: 'SS', label: 'SS' },
  { value: 'RH', label: 'RH' },
  { value: 'RM', label: 'RM' },
  { value: 'RS', label: 'RS' },
  { value: 'IM', label: 'IM' },
  { value: 'W', label: 'W' },
];

function Gt7CatalogScreen() {
  const { Button, Card, Input, Badge, Select } = window.GT7LeagueDesignSystem_258437;
  const season = window.GT7DATA?.season || 'GT7 League';
  const [tab, setTab] = React.useState('cars');
  const [carQuery, setCarQuery] = React.useState('');
  const [courseQuery, setCourseQuery] = React.useState('');
  const [carTyre, setCarTyre] = React.useState('');
  const [carPpMin, setCarPpMin] = React.useState('');
  const [carPpMax, setCarPpMax] = React.useState('');
  const [cars, setCars] = React.useState([]);
  const [courses, setCourses] = React.useState([]);
  const [templates, setTemplates] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState('');
  const [reloadTick, setReloadTick] = React.useState(0);

  const activeRows = tab === 'cars' ? cars : tab === 'courses' ? courses : templates;
  const activeCount = activeRows.length;
  const isCapped = activeCount === 100;
  const resultSummary = isCapped
    ? 'Showing up to 100 results from the current query.'
    : `${activeCount} results returned.`;
  const hasCarFilters = Boolean(
    carQuery.trim() || carTyre || carPpMin.trim() || carPpMax.trim(),
  );
  const hasCourseFilters = Boolean(courseQuery.trim());
  const isFiltered = tab === 'cars' ? hasCarFilters : tab === 'courses' ? hasCourseFilters : false;

  const debouncedCarQuery = useDebouncedValue(carQuery, 220);
  const debouncedCourseQuery = useDebouncedValue(courseQuery, 220);
  const debouncedCarPpMin = useDebouncedValue(carPpMin, 220);
  const debouncedCarPpMax = useDebouncedValue(carPpMax, 220);

  React.useEffect(() => {
    const controller = new AbortController();

    async function loadCatalog() {
      setLoading(true);
      setError('');

      try {
        const path = buildCatalogPath({
          tab,
          carQuery: debouncedCarQuery,
          courseQuery: debouncedCourseQuery,
          carTyre,
          carPpMin: debouncedCarPpMin,
          carPpMax: debouncedCarPpMax,
        });
        const rows = await fetchCatalogRows(path, controller.signal);
        if (tab === 'cars') setCars(rows);
        if (tab === 'courses') setCourses(rows);
        if (tab === 'templates') setTemplates(rows);
      } catch (loadError) {
        if (loadError?.name === 'AbortError') return;
        setError(loadError?.message || 'Unable to load GT7 catalog.');
      } finally {
        if (!controller.signal.aborted) setLoading(false);
      }
    }

    loadCatalog();
    return () => controller.abort();
  }, [
    tab,
    debouncedCarPpMax,
    debouncedCarPpMin,
    debouncedCarQuery,
    debouncedCourseQuery,
    carTyre,
    reloadTick,
  ]);

  const statusTone = error ? 'danger' : loading ? 'caution' : 'positive';
  const statusText = error ? 'Offline' : loading ? 'Updating' : 'Live';

  return (
    <div style={{ display: 'grid', gap: 18 }}>
      <section style={{ display: 'grid', gap: 14 }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'flex-end', justifyContent: 'space-between', gap: 16 }}>
          <div style={{ minWidth: 0 }}>
            <div style={{
              fontFamily: 'var(--font-display)',
              fontSize: 11,
              letterSpacing: '.14em',
              textTransform: 'uppercase',
              color: 'var(--accent)',
              marginBottom: 8,
            }}>
              {season}
            </div>
            <h1 style={{
              margin: 0,
              fontFamily: 'var(--font-display)',
              fontWeight: 700,
              fontSize: 34,
              lineHeight: 1.02,
              color: 'var(--text-strong)',
            }}>
              GT7 Catalog
            </h1>
            <p style={{ margin: '8px 0 0', fontSize: 14, color: 'var(--text-muted)', maxWidth: 720, lineHeight: 1.5 }}>
              Cars, courses, and daily race templates from the active snapshot.
            </p>
          </div>

          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>
            <Badge tone="neutral">Read only</Badge>
            <Badge tone={statusTone}>{statusText}</Badge>
          </div>
        </div>

        <Card style={{ display: 'grid', gap: 14 }}>
          <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'space-between', gap: 10 }}>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
              <Button variant={tab === 'cars' ? 'primary' : 'secondary'} size="sm" onClick={() => setTab('cars')}>
                Cars
              </Button>
              <Button variant={tab === 'courses' ? 'primary' : 'secondary'} size="sm" onClick={() => setTab('courses')}>
                Courses
              </Button>
              <Button variant={tab === 'templates' ? 'primary' : 'secondary'} size="sm" onClick={() => setTab('templates')}>
                Templates
              </Button>
            </div>

            <Button variant="ghost" size="sm" onClick={() => setReloadTick(t => t + 1)}>
              Refresh
            </Button>
          </div>

          {tab === 'cars' && (
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(140px, 1fr))', gap: 10 }}>
              <Input
                label="Maker or car"
                placeholder="Search maker or car"
                value={carQuery}
                onChange={event => setCarQuery(event.target.value)}
              />
              <Select
                label="Tyre"
                options={CAR_TYRE_OPTIONS}
                value={carTyre}
                onChange={event => setCarTyre(event.target.value)}
              />
              <Input
                label="PP min"
                type="number"
                inputMode="decimal"
                min="0"
                step="0.01"
                placeholder="Any"
                value={carPpMin}
                onChange={event => setCarPpMin(event.target.value)}
              />
              <Input
                label="PP max"
                type="number"
                inputMode="decimal"
                min="0"
                step="0.01"
                placeholder="Any"
                value={carPpMax}
                onChange={event => setCarPpMax(event.target.value)}
              />
            </div>
          )}

          {tab === 'courses' && (
            <Input
              label="Course search"
              placeholder="Search courses"
              value={courseQuery}
              onChange={event => setCourseQuery(event.target.value)}
            />
          )}

          {activeRows.length > 0 && !error && (
            <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8, color: 'var(--text-muted)', fontSize: 13, lineHeight: 1.4 }}>
              <span>{resultSummary}</span>
              {tab !== 'templates' && isFiltered && <Badge tone="caution">Filtered</Badge>}
            </div>
          )}
        </Card>
      </section>

      {error && (
        <Card accent="brand" style={{ display: 'grid', gap: 8 }}>
          <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
            <div style={{ minWidth: 0 }}>
              <div style={{
                fontFamily: 'var(--font-display)',
                fontSize: 12,
                fontWeight: 700,
                letterSpacing: '.12em',
                textTransform: 'uppercase',
                color: 'var(--red-300)',
              }}>
                Catalog request failed
              </div>
              <div style={{ marginTop: 5, color: 'var(--text-muted)', lineHeight: 1.45 }}>
                {error}
              </div>
            </div>
            <Button variant="secondary" size="sm" onClick={() => setReloadTick(t => t + 1)}>
              Retry
            </Button>
          </div>
        </Card>
      )}

      {loading && activeRows.length === 0 && !error && (
        <Card style={{ color: 'var(--text-muted)' }}>Loading catalog data...</Card>
      )}

      {!loading && !error && activeRows.length === 0 && (
        <Card style={{ display: 'grid', gap: 10 }}>
          <div style={{ fontFamily: 'var(--font-display)', fontSize: 12, fontWeight: 700, letterSpacing: '.12em', textTransform: 'uppercase', color: 'var(--text-muted)' }}>
            No rows
          </div>
          <div style={{ color: 'var(--text-muted)', lineHeight: 1.5 }}>
            {tab === 'templates' ? 'No daily race templates were returned.' : 'No rows matched the current filter.'}
          </div>
          {tab === 'cars' && hasCarFilters && (
            <Button
              variant="ghost"
              size="sm"
              onClick={() => {
                setCarQuery('');
                setCarTyre('');
                setCarPpMin('');
                setCarPpMax('');
              }}
            >
              Clear filters
            </Button>
          )}
          {tab === 'courses' && hasCourseFilters && (
            <Button variant="ghost" size="sm" onClick={() => setCourseQuery('')}>
              Clear filters
            </Button>
          )}
        </Card>
      )}

      {!error && activeRows.length > 0 && (
        <section style={{ display: 'grid', gap: 12 }}>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>
            <Badge tone="neutral">{tab === 'cars' ? 'Cars' : tab === 'courses' ? 'Courses' : 'Templates'}</Badge>
            <Badge tone={statusTone}>{loading ? 'Refreshing' : isCapped ? 'Up to 100 shown' : `${activeCount} loaded`}</Badge>
          </div>

          <CatalogGrid>
            {tab === 'cars' && cars.map((car, index) => <CarCard key={carKey(car, index)} car={car} />)}
            {tab === 'courses' && courses.map((course, index) => <CourseCard key={courseKey(course, index)} course={course} />)}
            {tab === 'templates' && templates.map((template, index) => <TemplateCard key={templateKey(template, index)} template={template} />)}
          </CatalogGrid>
        </section>
      )}
    </div>
  );
}

function CarCard({ car }) {
  return (
    <Card accent="brand" style={{ display: 'grid', gap: 12, minWidth: 0 }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12 }}>
        <div style={{ minWidth: 0 }}>
          <div style={{
            fontFamily: 'var(--font-display)',
            fontSize: 12,
            letterSpacing: '.12em',
            textTransform: 'uppercase',
            color: 'var(--text-muted)',
          }}>
            Car
          </div>
          <div style={{
            marginTop: 5,
            fontFamily: 'var(--font-display)',
            fontSize: 19,
            lineHeight: 1.15,
            fontWeight: 700,
            color: 'var(--text-strong)',
          }}>
            {textOr(car.short_name, 'Unnamed car')}
          </div>
        </div>
        <Badge tone="neutral">#{textOr(car.car_id, '—')}</Badge>
      </div>

      <div style={{ display: 'grid', gap: 8 }}>
        <CatalogFact label="Maker" value={textOr(car.maker_name, `Maker ${textOr(car.maker_id, '—')}`)} />
        <CatalogFact label="Search" value={textOr(car.search_text, '—')} mono />
      </div>
    </Card>
  );
}

function CourseCard({ course }) {
  return (
    <Card accent="cyan" style={{ display: 'grid', gap: 12, minWidth: 0 }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12 }}>
        <div style={{ minWidth: 0 }}>
          <div style={{
            fontFamily: 'var(--font-display)',
            fontSize: 12,
            letterSpacing: '.12em',
            textTransform: 'uppercase',
            color: 'var(--text-muted)',
          }}>
            Course
          </div>
          <div style={{
            marginTop: 5,
            fontFamily: 'var(--font-display)',
            fontSize: 19,
            lineHeight: 1.15,
            fontWeight: 700,
            color: 'var(--text-strong)',
          }}>
            {textOr(course.name, 'Unnamed course')}
          </div>
        </div>

        <div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'flex-end', gap: 6 }}>
          {course.category && <Badge tone="pole">{course.category}</Badge>}
          <Badge tone={truthy(course.supports_rain) ? 'positive' : 'caution'}>{truthy(course.supports_rain) ? 'Rain' : 'Dry'}</Badge>
          {truthy(course.is_oval) && <Badge tone="neutral">Oval</Badge>}
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: 10 }}>
        <CatalogFact label="Length" value={formatMeters(course.length_m)} mono />
        <CatalogFact label="Straight" value={formatMeters(course.longest_straight_m)} mono />
        <CatalogFact label="Corners" value={formatNumber(course.num_corners)} mono />
        <CatalogFact label="Pit delta" value={formatSeconds(course.pit_lane_delta_s)} mono />
        <CatalogFact label="Elevation" value={formatMeters(course.elevation_diff_m)} mono />
        <CatalogFact label="Course ID" value={textOr(course.course_id, '—')} mono />
      </div>
    </Card>
  );
}

function TemplateCard({ template }) {
  return (
    <Card accent="gold" style={{ display: 'grid', gap: 12, minWidth: 0 }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12 }}>
        <div style={{ minWidth: 0 }}>
          <div style={{
            fontFamily: 'var(--font-display)',
            fontSize: 12,
            letterSpacing: '.12em',
            textTransform: 'uppercase',
            color: 'var(--text-muted)',
          }}>
            Daily race template
          </div>
          <div style={{
            marginTop: 5,
            fontFamily: 'var(--font-display)',
            fontSize: 19,
            lineHeight: 1.15,
            fontWeight: 700,
            color: 'var(--text-strong)',
          }}>
            {textOr(template.source_date, 'Unknown date')} · Race {textOr(template.race_slot, '—')}
          </div>
        </div>

        <div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'flex-end', gap: 6 }}>
          {truthy(template.bop) && <Badge tone="positive">BoP</Badge>}
          {template.category && <Badge tone="pole">{template.category}</Badge>}
          {template.spec && <Badge tone="neutral">{template.spec}</Badge>}
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: 10 }}>
        <CatalogFact label="Course" value={textOr(template.course_id, '—')} mono />
        <CatalogFact label="Laps" value={textOr(template.laps, '—')} mono />
        <CatalogFact label="Start" value={textOr(template.start_type, '—')} />
        <CatalogFact label="Car type" value={textOr(template.car_type, '—')} />
        <CatalogFact label="Fuel" value={formatMultiplier(template.fuel_consumption)} mono />
        <CatalogFact label="Tyre wear" value={formatMultiplier(template.tyre_wear)} mono />
      </div>

      <div style={{ display: 'grid', gap: 8, color: 'var(--text-muted)', fontSize: 12.5, lineHeight: 1.45 }}>
        <DetailLine label="Cars" value={template.cars} />
        <DetailLine label="Tyres" value={template.tyres} />
        <DetailLine label="Required" value={template.required_tyres} />
        <DetailLine label="Damage" value={template.damage} />
        <DetailLine label="Time" value={template.race_time ? `${template.race_time}${template.offset_minutes != null ? ` · ${formatOffsetMinutes(template.offset_minutes)}` : ''}` : formatOffsetMinutes(template.offset_minutes)} />
      </div>
    </Card>
  );
}

function CatalogFact({ label, value, mono = false }) {
  return (
    <div style={{ minWidth: 0 }}>
      <div style={{
        fontFamily: 'var(--font-display)',
        fontSize: 10.5,
        letterSpacing: '.12em',
        textTransform: 'uppercase',
        color: 'var(--text-faint)',
      }}>
        {label}
      </div>
      <div style={{
        marginTop: 4,
        fontFamily: mono ? 'var(--font-mono)' : 'var(--font-body)',
        fontSize: 14,
        lineHeight: 1.35,
        color: 'var(--text-strong)',
        whiteSpace: 'nowrap',
        overflow: 'hidden',
        textOverflow: 'ellipsis',
      }}>
        {textOr(value, '—')}
      </div>
    </div>
  );
}

function DetailLine({ label, value }) {
  return (
    <div style={{ minWidth: 0 }}>
      <span style={{ fontFamily: 'var(--font-display)', fontSize: 10, letterSpacing: '.12em', textTransform: 'uppercase', color: 'var(--text-faint)' }}>
        {label}
      </span>
      <span style={{ display: 'block', marginTop: 3, color: 'var(--text-muted)', wordBreak: 'break-word' }}>
        {formatDetailValue(value)}
      </span>
    </div>
  );
}

function CatalogGrid({ children }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))', gap: 12 }}>
      {children}
    </div>
  );
}

function useDebouncedValue(value, delayMs) {
  const [debounced, setDebounced] = React.useState(value);

  React.useEffect(() => {
    const id = window.setTimeout(() => setDebounced(value), delayMs);
    return () => window.clearTimeout(id);
  }, [value, delayMs]);

  return debounced;
}

function buildCatalogPath({ tab, carQuery, courseQuery, carTyre, carPpMin, carPpMax }) {
  const params = new URLSearchParams();
  if (tab === 'cars') {
    if (carQuery.trim()) params.set('q', carQuery.trim());
    if (carTyre) params.set('tyre', carTyre);
    if (carPpMin.trim()) params.set('ppMin', carPpMin.trim());
    if (carPpMax.trim()) params.set('ppMax', carPpMax.trim());
    return `/api/gt7/cars${params.toString() ? `?${params}` : ''}`;
  }
  if (tab === 'courses') {
    if (courseQuery.trim()) params.set('q', courseQuery.trim());
    return `/api/gt7/courses${params.toString() ? `?${params}` : ''}`;
  }
  return '/api/gt7/daily-race-templates';
}

async function fetchCatalogRows(path, signal) {
  const response = await fetch(path, { signal, headers: { Accept: 'application/json' } });
  const bodyText = await response.text();
  const payload = bodyText ? safeJsonParse(bodyText) : null;

  if (!response.ok) {
    const detail = payload && typeof payload === 'object'
      ? payload.error || payload.message || payload.detail
      : bodyText;
    throw new Error(detail ? `Catalog request failed: ${detail}` : `Catalog request failed: HTTP ${response.status}`);
  }

  return normalizeRows(payload);
}

function normalizeRows(payload) {
  if (Array.isArray(payload)) return payload;
  if (!payload || typeof payload !== 'object') return [];
  if (Array.isArray(payload.data)) return payload.data;
  if (Array.isArray(payload.rows)) return payload.rows;
  if (Array.isArray(payload.items)) return payload.items;
  return [];
}

function safeJsonParse(text) {
  try {
    return JSON.parse(text);
  } catch {
    return text;
  }
}

function textOr(value, fallback = '—') {
  if (value == null || value === '') return fallback;
  return String(value);
}

function truthy(value) {
  return value === true || value === 'true' || value === 1 || value === '1' || value === 'yes';
}

function formatNumber(value) {
  const num = Number(value);
  return Number.isFinite(num) ? num.toLocaleString() : '—';
}

function formatMeters(value) {
  const num = Number(value);
  return Number.isFinite(num) ? `${num.toLocaleString()} m` : '—';
}

function formatSeconds(value) {
  const num = Number(value);
  return Number.isFinite(num) ? `${num.toLocaleString()} s` : '—';
}

function formatMultiplier(value) {
  const num = Number(value);
  return Number.isFinite(num) ? `${num}x` : '—';
}

function formatOffsetMinutes(value) {
  const num = Number(value);
  if (!Number.isFinite(num)) return '—';
  if (num === 0) return 'On schedule';
  return `${num > 0 ? '+' : ''}${num} min`;
}

function formatDetailValue(value) {
  if (Array.isArray(value)) {
    if (!value.length) return '—';
    return value.map(v => (v == null ? '—' : String(v))).join(' · ');
  }

  if (value && typeof value === 'object') {
    const entries = Object.entries(value);
    if (!entries.length) return '—';
    return entries.map(([key, item]) => `${key}: ${item == null ? '—' : String(item)}`).join(' · ');
  }

  return textOr(value, '—');
}

function carKey(car, index) {
  return textOr(car?.car_id, textOr(car?.short_name, `car-${index}`));
}

function courseKey(course, index) {
  return textOr(course?.course_id, textOr(course?.name, `course-${index}`));
}

function templateKey(template, index) {
  return textOr(template?.template_id, textOr(template?.source_date, `template-${index}`));
}

window.Gt7CatalogScreen = Gt7CatalogScreen;
